// Package dbsvc
// Package dbsvc
// @Author: zhangdi
package dbsvc

import (
	"errors"
	"fmt"
	"server/application/constant/enums"
	"server/application/db/system/columns"
	"server/application/db/system/dbdto"
	"server/application/db/system/entity"
	"server/application/db/system/repository"
	"server/pkg/utils"
	"server/pkg/where"
	"server/setting"
)

// SysMenuCreate 创建
func SysMenuCreate(dtoCreate *dbdto.SysMenuCreate) (*dbdto.SysMenuInfo, error) {
	info, _ := SysMenuFindOne(where.Format(where.Opt(columns.SysMenuName, "=", dtoCreate.Name)))
	if info.ID > 0 {
		return nil, errors.New("该路由key已存在，换一个吧")
	}
	return repository.Create[
		entity.SysMenu, dbdto.SysMenuCreate, dbdto.SysMenuInfo,
	](dtoCreate)
}

// SysMenuFindOne 查找
func SysMenuFindOne(wheres []*where.Condition) (*dbdto.SysMenuInfo, error) {
	return repository.FindOne[
		entity.SysMenu, dbdto.SysMenuInfo,
	](wheres, false)
}

func SysMenuFindOneById(id uint) (*dbdto.SysMenuInfo, error) {
	wheres := where.FormatOne("id", "=", id)
	return repository.FindOne[
		entity.SysMenu, dbdto.SysMenuInfo,
	](wheres, false)
}

// SysMenuFindList 查找列表
func SysMenuFindList(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysMenuInfo, error) {
	return repository.FindList[
		entity.SysMenu, dbdto.SysMenuInfo](wheres, extra, false)
}

// SysMenuSearch 搜索
func SysMenuSearch(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysMenuInfo, int64) {
	total, err := SysMenuGetTotal(wheres)
	list := make([]*dbdto.SysMenuInfo, 0)
	if err != nil || total <= 0 {
		return list, 0
	}
	list, err = SysMenuFindList(wheres, extra)
	return list, total
}

// SysMenuUpdate 更新，字段可按规则传入，传入那个修改哪个
func SysMenuUpdate(wheres []*where.Condition, dtoUpdate *dbdto.SysMenuUpdate, columnsCfg ...string) error {
	return repository.Update[
		entity.SysMenu, dbdto.SysMenuUpdate](wheres, dtoUpdate, columnsCfg...)
}

// SysMenuDelete 删除（deleted_at存在则是软删除）
func SysMenuDelete(wheres []*where.Condition) error {
	return repository.Delete[entity.SysMenu](wheres, setting.UseSoftDelete)
}

// SysMenuGetTotal 获取总数
func SysMenuGetTotal(wheres []*where.Condition) (int64, error) {
	return repository.GetTotal[entity.SysMenu](wheres)
}

// SysMenuGetNames 获取name列表
func SysMenuGetNames() []string {
	list, err := SysMenuFindList(where.Format(), &where.Extra{})
	if err != nil {
		return nil
	}
	var names []string
	for _, info := range list {
		names = append(names, info.Name)
	}
	return names
}

// SysMenuAuthFilter 菜单权限过滤
func SysMenuAuthFilter(tree []SysMenuTree, userId uint) []SysMenuTree {
	if SysUserIsSuperAdmin(userId) {
		return tree //如果是超级管理员则则直接返回
	}
	roleIds := SysUserGetRoleIds(userId)
	permissionNames := SysRolePermissionGetFullName(roleIds...)
	filterAuthTree := sysMenuFilterAuthTree(tree, permissionNames)
	return filterAuthTree
}

// 递归过滤掉无权限的节点
func sysMenuFilterAuthTree(tree []SysMenuTree, permissionNames []string) []SysMenuTree {
	filteredTree := []SysMenuTree{}

	for i := 0; i < len(tree); i++ {
		if len(tree[i].Children) > 0 {
			// 递归遍历子节点，并获取过滤后的子节点
			subTree := sysMenuFilterAuthTree(tree[i].Children, permissionNames)
			// 如果子节点不为空，则添加到当前节点的子节点中
			if len(subTree) > 0 {
				tree[i].Children = subTree
				filteredTree = append(filteredTree, tree[i])
			}
		} else {

			//叶子节点，进行权限判断
			menuName := tree[i].Name
			menuPermissionIndexName := fmt.Sprintf("%s.%s", menuName, enums.BtnAuthIndex)
			if utils.ArrContains(permissionNames, menuPermissionIndexName) {
				// 如果满足条件，则将当前节点添加到过滤后的树中
				filteredTree = append(filteredTree, tree[i])
			}
		}
	}

	// 返回过滤后的树
	return filteredTree
}
